package yf.mall.utils;

import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import yf.mall.entity.custom.PageQuery;

import java.util.List;

/**
 * description: 递归分页查询器
 *
 * @author yxmds
 * @version V1.0
 * @date 2020/2/3 5:12 PM
 */
public class RecursionPageQuerier<D> {

    /**
     * 默认按1000数据量查询
     */
    private int limit = 1000;


    /**
     * 最大执行次数
     */
    private int maxNum = 20;

    public RecursionPageQuerier() {

    }


    /**
     * description: 构造方法
     *
     * @param limit 闲置数据的条数
     * @return
     * @author yxmds
     * @date 2020/2/3 5:23 PM
     **/
    public RecursionPageQuerier(int limit) {
        this.limit = limit;
    }


    /**
     * description: 构造方法
     *
     * @param limit  限制数据的条数
     * @param maxNum 最大执行次数
     * @return
     * @author yxmds
     * @date 2020/2/3 5:23 PM
     **/
    public RecursionPageQuerier(int limit, int maxNum) {

        this.limit = limit;
        this.maxNum = maxNum;
    }


    public List<D> query(Function<D> function) {

        //定义返回结果
        List<D> result = Lists.newLinkedList();

        //构建分页查询条件
        PageQuery pageQuery = new PageQuery(1, limit);

        int size;

        int executeNum = 0;
        do {
            List<D> list = function.apply(pageQuery);

            if (list == null) {
                return result;
            }

            size = list.size();

            pageQuery.setPageNumber(pageQuery.getPageNumber() + 1);

            if (CollectionUtils.isNotEmpty(list)) {
                result.addAll(list);
            }

            //执行次数+1
            executeNum++;

            if (size < limit) {
                return result;
            }

        } while (size == limit && executeNum < maxNum);

        return result;
    }


    /**
     * description: 定义的执行函数
     *
     * @author yxmds
     * @version V1.0
     * @date 2020/2/3 5:17 PM
     */
    public interface Function<D> {

        /**
         * description: 执行函数
         *
         * @param pageQuery 分页查询条件
         * @return
         * @author yxmds
         * @date 2020/2/3 5:17 PM
         **/
        List<D> apply(PageQuery pageQuery);
    }
}
